home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 November
/
Macworld (1999-11).dmg
/
Updaters
/
WhiteCap 3.0.4
/
WhiteCap Source.sit
/
WhiteCap Source
/
mainWinamp.cpp
< prev
next >
Wrap
Text File
|
1999-08-29
|
11KB
|
466 lines
// Winamp test visualization library v1.0
#include <windows.h>
#include "WhiteCap.h"
#include "EgOSUtils.h"
#include "RectUtils.h"
#include "CEgFileSpec.h"
#include "vis.h"
char szAppName[] = "WhiteCap"; // Our window class, etc
// returns a winampVisModule when requested. Used in hdr, below
winampVisModule *getModule(int which);
// "member" functions
void config(struct winampVisModule *this_mod); // configuration dialog
int init(struct winampVisModule *this_mod); // initialization for module
int Go(struct winampVisModule *this_mod); // rendering for module 1
void quit(struct winampVisModule *this_mod); // deinitialization for module
// our window procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
HWND hMainWnd; // main window handle
// Module header, includes version, description, and address of the module retriever function
winampVisHeader hdr = { VIS_HDRVER, "WhiteCap", getModule };
class WhiteCap;
static WhiteCap* gWC = NULL;
static float gSample[ NUM_SAMPLE_BINS ];
winampVisModule gWCModule =
{
"WhiteCap",
NULL, // hwndParent
NULL, // hDllInstance
0, // sRate
0, // nCh
25, // latencyMS
25, // delayMS
2, // spectrumNch
0, // waveformNch
{ 0, }, // spectrumData
{ 0, }, // waveformData
config,
init,
Go,
quit
};
// this is the only exported symbol. returns our main header.
// if you are compiling C++, the extern "C" { is necessary, so we just #ifdef it
#ifdef __cplusplus
extern "C" {
#endif
__declspec( dllexport ) winampVisHeader *winampVisGetHeader()
{
return &hdr;
}
#ifdef __cplusplus
}
#endif
// getmodule routine from the main header. Returns NULL if an invalid module was requested,
// otherwise returns either mod1, mod2 or mod3 depending on 'which'.
winampVisModule *getModule(int inWhich )
{
if ( inWhich == 0 )
return &gWCModule;
else
return NULL;
}
// configuration. Passed this_mod, as a "this" parameter. Allows you to make one configuration
// function that shares code for all your modules (you don't HAVE to use it though, you can make
// config1(), config2(), etc...)
void config(struct winampVisModule *this_mod)
{
MessageBox(this_mod->hwndParent,"Right click on the WhiteCap window to change configs.\n"
"Be sure to read the readme file!\n", "", MB_OK);
}
// initialization. Registers our window class, creates our window, etc. Again, this one works for
// both modules, but you could make init1() and init2()...
// returns 0 on success, 1 on failure.
int init(struct winampVisModule *this_mod)
{
EgOSUtils::Initialize();
PixPort::Startup();
{ // Register our window class
WNDCLASS wc;
memset(&wc,0,sizeof(wc));
wc.lpfnWndProc = WndProc; // our window procedure
wc.hInstance = this_mod->hDllInstance; // hInstance of DLL
wc.lpszClassName = szAppName; // our window class name
wc.hCursor = ::LoadCursor( NULL, IDC_ARROW );
//wc.hbrBackground = ::GetSysColorBrush( COLOR_BACKGROUND + 1 );
wc.style = CS_BYTEALIGNCLIENT;
::RegisterClass(&wc);
}
// Make A WhiteCap!
CEgFileSpec folder;
folder.AssignFolder( "Plugins\\WhiteCap Configs\\" );
gWC = new WhiteCap( folder );
hMainWnd = CreateWindowEx(
WS_EX_TOOLWINDOW, // these exstyles put a nice small frame,
// but also a button in the taskbar
szAppName, // our window class name
this_mod->description, // use description for a window title
WS_SYSMENU | WS_THICKFRAME, // make the window visible with a close button
0,0, // screen position (read from config)
200,200, // width & height of window (need to adjust client area later)
this_mod->hwndParent, // parent window (winamp main window)
NULL, // no menu
this_mod->hDllInstance, // hInstance of DLL
0); // no window creation data
SetWindowLong(hMainWnd,GWL_USERDATA,(LONG)this_mod); // set our user data to a "this" pointer
gWC -> SetWinPort( hMainWnd );
::ShowWindow( hMainWnd, SW_SHOWNORMAL );
return 0;
}
#define _ABS( x ) (( (x) > 0 ) ? (x) : (-x))
int Go(struct winampVisModule *this_mod)
{
long sum, idx;
/*
idx = 8;
for ( int i = 0; i < NUM_SAMPLE_BINS; i++ ) {
sum = 0;
for ( int j = 0; j < i+3; j++, idx++ )
sum += ((unsigned) this_mod->spectrumData[0][idx] );
gSample[ i ] = sum;
}
idx = 8;
for ( int i = 0; i < NUM_SAMPLE_BINS; i++ ) {
sum = 0;
for ( int j = 0; j < i+3; j++, idx++ )
sum += ((unsigned) this_mod->spectrumData[1][idx] );
gSample[ i ] = ((float) sum + gSample[ i ]) / (350.0);
}*/
int i, j;
/*
idx = 4;
for ( sum = 0, j = 0; j < 2; j++, idx++ ) {
sum += ((unsigned long) this_mod->spectrumData[0][idx]) + ((unsigned long) this_mod->spectrumData[1][idx]);
}
gSample[ 0 ] = sum / 400;
for ( sum = 0, j = 0; j < 3; j++, idx++ ) {
sum += ((unsigned long) this_mod->spectrumData[0][idx]) + ((unsigned long) this_mod->spectrumData[1][idx]);
}
gSample[ 1 ] = sum / 400;
for ( sum = 0, j = 0; j < 4; j++, idx++ ) {
sum += ((unsigned long) this_mod->spectrumData[0][idx]) + ((unsigned long) this_mod->spectrumData[1][idx]);
}
gSample[ 2 ] = sum / 400;
for ( sum = 0, j = 0; j < 5; j++, idx++ ) {
sum += ((unsigned long) this_mod->spectrumData[0][idx]) + ((unsigned long) this_mod->spectrumData[1][idx]);
}
gSample[ 4 ] = sum / 400;*/
float factor, binVal;
float scale = .85 * UNIV_MAG_SCALE;
idx = 15;
for ( i = 0; i < NUM_SAMPLE_BINS; i++ ) {
sum = 0;
for ( j = 0; j < 8; j++, idx++ )
sum += ((unsigned) this_mod->spectrumData[0][idx]);
gSample[ i ] = sum;
}
idx = 15;
for ( i = 0; i < NUM_SAMPLE_BINS; i++ ) {
sum = 0;
for ( j = 0; j < 8; j++, idx++ )
sum += ((unsigned) this_mod->spectrumData[1][idx]);
binVal = ((float) sum + gSample[ i ]) * (0.81 + (float) i / 24);
/*
factor = .4 + .27 / ( 1.50 * binVal + .4 );
if ( factor < 1 )
binVal *= factor;
gSample[ i ] = .6 * binVal;*/
gSample[ i ] = scale * ( log( .00401785 * binVal + 1 ) ); // = .85 * ( log( .006429 * binVal + 1.6 ) - log( 1.6 ) );
}
gSample[ 0 ] *= 0.45;
gSample[ 1 ] *= 0.65;
long time = ::timeGetTime();
gWC -> RecordSample( time, gSample );
gWC -> Draw();
return 0;
}
/*
sum += ((unsigned) this_mod->spectrumData[1][idx]);
binVal = ((float) sum + gSample[ i ]) * (0.81 + (float) i / 17) / ( 140 );
gSample[ i ] = 1.5 * ( log( .008 * binVal + 1.4 ) - log( 1.4 ) );
*/
// cleanup (opposite of init()). Destroys the window, unregisters the window class
void quit(struct winampVisModule *this_mod)
{
if ( gWC ) {/*
RECT wr;
::GetClientRect( hMainWnd, &wr );
UtilStr str;
str.Append( wr.top );
str.Append( " " );
str.Append( wr.left );
str.Append( " " );
str.Append( wr.bottom );
str.Append( " " );
str.Append( wr.right );
str.Append( " " );
EgOSUtils::ShowMsg( str );*/
delete gWC;
gWC = NULL;
}
PixPort::Shutdown();
::DestroyWindow(hMainWnd); // delete our window
::UnregisterClass(szAppName,this_mod->hDllInstance); // unregister window class
}
/*
// render function for oscilliscope. Returns 0 if successful, 1 if visualization should end.
int render1(struct winampVisModule *this_mod)
{
int x, y;
// clear background
Rectangle(memDC,0,0,288,256);
// draw oscilliscope
for (y = 0; y < this_mod->nCh; y ++)
{
MoveToEx(memDC,0,(y*256)>>(this_mod->nCh-1),NULL);
for (x = 0; x < 288; x ++)
{
LineTo(memDC,x,(y*256 + this_mod->waveformData[y][x]^128)>>(this_mod->nCh-1));
}
}
{ // copy doublebuffer to window
HDC hdc = GetDC(hMainWnd);
BitBlt(hdc,0,0,288,256,memDC,0,0,SRCCOPY);
ReleaseDC(hMainWnd,hdc);
}
return 0;
}
// render function for analyser. Returns 0 if successful, 1 if visualization should end.
int render2(struct winampVisModule *this_mod)
{
int x, y;
// clear background
Rectangle(memDC,0,0,288,256);
// draw analyser
for (y = 0; y < this_mod->nCh; y ++)
{
for (x = 0; x < 288; x ++)
{
MoveToEx(memDC,x,(y*256+256)>>(this_mod->nCh-1),NULL);
LineTo(memDC,x,(y*256 + 256 - this_mod->spectrumData[y][x])>>(this_mod->nCh-1));
}
}
{ // copy doublebuffer to window
HDC hdc = GetDC(hMainWnd);
BitBlt(hdc,0,0,288,256,memDC,0,0,SRCCOPY);
ReleaseDC(hMainWnd,hdc);
}
return 0;
}
// render function for VU meter. Returns 0 if successful, 1 if visualization should end.
int render3(struct winampVisModule *this_mod)
{
int x, y;
// clear background
Rectangle(memDC,0,0,256,32);
// draw VU meter
for (y = 0; y < 2; y ++)
{
int last=this_mod->waveformData[y][0];
int total=0;
for (x = 1; x < 576; x ++)
{
total += abs(last - this_mod->waveformData[y][x]);
last = this_mod->waveformData[y][x];
}
total /= 288;
if (total > 127) total = 127;
if (y) Rectangle(memDC,128,0,128+total,32);
else Rectangle(memDC,128-total,0,128,32);
}
{ // copy doublebuffer to window
HDC hdc = GetDC(hMainWnd);
BitBlt(hdc,0,0,256,32,memDC,0,0,SRCCOPY);
ReleaseDC(hMainWnd,hdc);
}
return 0;
}
*/
int WINAPI WinMain( HINSTANCE hInst, /*Win32 entry-point routine */
HINSTANCE hPreInst,
LPSTR lpszCmdLine,
int nCmdShow )
{
MSG lpMsg;
init( &gWCModule );
while( GetMessage( &lpMsg, NULL, 0, 0 ) ) /* begin the message loop */
{
Go( &gWCModule );
TranslateMessage( &lpMsg );
DispatchMessage( &lpMsg );
}
return( lpMsg.wParam);
}
// window procedure for our window
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static long sLastClickTime = 0;
switch ( message )
{
/*
case WM_NCLMOUSEMOVE:
case WM_MOUSEMOVED:
if ( gWC -> IsAtFullScreen() )
return 0;
break;
case WM_NCRBUTTONDOWN:
if ( ! gWC -> IsAtFullScreen() )
break;*/
case WM_RBUTTONDOWN:
if ( (wParam & MK_RBUTTON) && gWC )
gWC -> SelectConfig();
return 0;
break;
//case WM_NCLBUTTONDOWN:
case WM_LBUTTONDOWN:
if ( gWC -> IsFullScreen() )
gWC -> SetFullScreen( false );
else if ( message == WM_LBUTTONDOWN ) {
long curTime = EgOSUtils::CurTimeMS();
if ( curTime - 300 < sLastClickTime )
gWC -> SetFullScreen( true );
else
sLastClickTime = curTime;
}
return 0;
break;
case WM_CREATE: return 0;
case WM_ERASEBKGND: return 0;
case WM_PAINT:
{ // update from doublebuffer
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
Rect r;
SetRect( &r, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom );
gWC -> RefreshRect( r );
gWC -> Draw();
EndPaint( hwnd, &ps );
}
return 0;
case WM_DESTROY: PostQuitMessage(0); return 0;
case WM_KEYDOWN: // pass keyboard messages to main winamp window (for processing)
case WM_KEYUP:
{ // get this_mod from our window's user data
winampVisModule *this_mod = (winampVisModule *) GetWindowLong(hwnd,GWL_USERDATA);
PostMessage(this_mod->hwndParent,message,wParam,lParam);
}
return 0;
case WM_MOVE:
return 0;
case WM_SIZE:
{
if ( gWC ) {
if ( ! gWC -> IsFullScreen() ) {
Rect r;
gWC -> GetWinRect( r );
gWC -> SetWinPort( hwnd, &r );
}
}
}
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}